package com.lt.bcra.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lt.bcra.client.FeignSms;
import com.lt.bcra.entity.vo.BcraPersonalInfoVo;
import com.lt.bcra.entity.BcraPersonalInfo;
import com.lt.bcra.entity.vo.ExcelPersonalInfo;
import com.lt.bcra.exception.BaseException;
import com.lt.bcra.mapper.BcraPersonalInfoMapper;
import com.lt.bcra.result.ResponseEnum;
import com.lt.bcra.result.ResultData;
import com.lt.bcra.service.BcraPersonalInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lt.bcra.utils.MD5Utils;
import lt.bcra.jwt.JwtHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 用户信息登录注册表 服务实现类
 * </p>
 *
 * @author LuoTian
 * @since 2022-05-23
 */
@Service
public class BcraPersonalInfoServiceImpl extends ServiceImpl<BcraPersonalInfoMapper, BcraPersonalInfo> implements BcraPersonalInfoService {

    @Autowired
    private BcraPersonalInfoMapper bcraPersonalInfoMapper;

    @Autowired
    private FeignSms feignSms;
    /**
     * 条件分页查询
     *
     * @return
     */
    @Override
    public ResultData listByPages(Long current, Long size, BcraPersonalInfoVo bcraPersonalInfoVo) {
        Page<BcraPersonalInfo> pageParam = new Page<>(current, size);

        //条件筛选
        QueryWrapper<BcraPersonalInfo> queryWrapper = selectSearch(bcraPersonalInfoVo);

        bcraPersonalInfoMapper.selectPage(pageParam, queryWrapper);

        List<BcraPersonalInfo> records = pageParam.getRecords();//当前页存在记录
        long total = pageParam.getTotal();//总条数
        long current1 = pageParam.getCurrent();//当前页码
        long pages = pageParam.getPages();//一共页数
        long size1 = pageParam.getSize();//每页条数

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("records", records);
        map.put("total", total);
        map.put("current", current1);
        map.put("pages", pages);
        map.put("size", size1);

        return ResultData.getResult(map);
    }

    @Override
    public ResultData registerUser(BcraPersonalInfo bcraPersonalInfo) {
        bcraPersonalInfo.setRole("user");
        String phone = bcraPersonalInfo.getPhone();

        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        BcraPersonalInfo selectOne = bcraPersonalInfoMapper.selectOne(queryWrapper);

        if (selectOne != null) {
            throw new BaseException(ResponseEnum.MOBILE_SAME_ERROR);
        }

        int ok = bcraPersonalInfoMapper.insert(bcraPersonalInfo);
        if (ok != 1) {
            throw new BaseException(ResponseEnum.CREATE_DATA_ERROR);
        }
        return ResultData.getResult(ok);
    }

    @Override
    public ResultData updateInfo(BcraPersonalInfo bcraPersonalInfo) {
        String phone = bcraPersonalInfo.getPhone();
        Integer id = bcraPersonalInfo.getId();

        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone).ne("id", id);
        if (bcraPersonalInfoMapper.selectOne(queryWrapper) != null) {
            throw new BaseException(ResponseEnum.MOBILE_SAME_ERROR);
        }
        int ok = bcraPersonalInfoMapper.updateById(bcraPersonalInfo);
        return ResultData.getResult(ok);
    }

    @Override
    public ResultData frozenUser(Integer id) {
        String status = bcraPersonalInfoMapper.selectById(id).getStatus();

        UpdateWrapper<BcraPersonalInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);

        updateWrapper.set(status.equals("activation"), "status", "frozen");

        updateWrapper.set(status.equals("frozen"), "status", "activation");

        int update = bcraPersonalInfoMapper.update(null, updateWrapper);

        if (update != 1) {
            throw new BaseException(ResponseEnum.FROZEN_UPDATE_ERROR); //冻结异常
        }
        return ResultData.getResult(update);

    }

    @Override
    public ResultData getAllPhone() {
        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("phone");
        List<BcraPersonalInfo> bcraPersonalInfos = bcraPersonalInfoMapper.selectList(queryWrapper);
        if (bcraPersonalInfos == null) {
            throw new BaseException(ResponseEnum.SELECT_DATA_ERROR);
        }
        List<String> phoneList = new ArrayList<>();
        for (BcraPersonalInfo info : bcraPersonalInfos) {
            phoneList.add(info.getPhone());
        }
        return ResultData.getResult(phoneList);
    }

    @Override
    public ResultData loginUser(String phone, String password) {
        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);

        BcraPersonalInfo bcraPersonalInfo = bcraPersonalInfoMapper.selectOne(queryWrapper);
        if (bcraPersonalInfo == null) {
            throw new BaseException(ResponseEnum.LOGIN_MOBILE_ERROR);
        }

        if (!bcraPersonalInfo.getPassword().equals(password)) {
            throw new BaseException(ResponseEnum.LOGIN_PASSWORD_ERROR);
        }
        if (bcraPersonalInfo.getStatus().equals("frozen")) {
            throw new BaseException(ResponseEnum.LOGIN_LOKED_ERROR);
        }
        //md5实现加密解密
        String md5Pwd = MD5Utils.md5(password);

        //设置token
        String token = JwtHelper.createToken(bcraPersonalInfo.getId(), phone);
        Map<String,Object> map =new HashMap<>();
        map.put("token",token);
        map.put("information",bcraPersonalInfo);
        map.put("md5Pwd",md5Pwd);

        return ResultData.getResult(map);
    }

    @Override
    public ResultData loginBySms(String phone) {
        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);

        BcraPersonalInfo bcraPersonalInfo = bcraPersonalInfoMapper.selectOne(queryWrapper);
        if (bcraPersonalInfo == null) {
            throw new BaseException(ResponseEnum.LOGIN_MOBILE_ERROR);
        }
        if (bcraPersonalInfo.getStatus().equals("frozen")) {
            throw new BaseException(ResponseEnum.LOGIN_LOKED_ERROR);
        }

        //设置token
        String token = JwtHelper.createToken(bcraPersonalInfo.getId(), phone);

        //远程调用发送验证码
        Map<String,Object> map =new HashMap<>();
        String code = (String) feignSms.sendCode(phone).getBody();
        map.put("code",code);
        map.put("information",bcraPersonalInfo);
        map.put("token",token);

        return ResultData.getResult(map);
    }

    @Override
    public ResultData checkToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        boolean result = JwtHelper.checkToken(token);

        if (result){
            Map<String,String> map =new HashMap<>();
            Integer id = JwtHelper.getId(token);
            String phone = JwtHelper.getPhone(token);
            map.put("id",id.toString());
            map.put("phone",phone);

            return ResultData.getResult(map);
        }else {
            throw new BaseException(ResponseEnum.LOGIN_AUTH_ERROR);
        }
    }

    @Override
    public BcraPersonalInfo selectWxInfoOpenId(String openid) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("open_id",openid);
        BcraPersonalInfo bcraPersonalInfo = bcraPersonalInfoMapper.selectOne(queryWrapper);
        return bcraPersonalInfo;
    }


    @Override
    public void exportExcel(HttpServletResponse response, BcraPersonalInfoVo bcraPersonalInfoVo) throws BaseException {
        QueryWrapper<BcraPersonalInfo> queryWrapper = selectSearch(bcraPersonalInfoVo);
        //查找所有符合条件且不带分页的列表信息
        List<BcraPersonalInfo> bcraPersonalInfoList = bcraPersonalInfoMapper.selectList(queryWrapper);

        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码和easyexcel没有关系
            String fileName = URLEncoder.encode("个人信息", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            List<ExcelPersonalInfo> excelPersonalInfoList = new ArrayList<>();

            int number=0;

            for (BcraPersonalInfo info : bcraPersonalInfoList) {
                ExcelPersonalInfo excelPersonalInfo = new ExcelPersonalInfo();
                //对象转化
                BeanUtils.copyProperties(info, excelPersonalInfo, ExcelPersonalInfo.class);

                excelPersonalInfo.setNumber(++number);

                //localDateTime转化为String
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime time = info.getCreateTime();
                String localTime = df.format(time);
                excelPersonalInfo.setCreateTime(localTime);

                excelPersonalInfoList.add(excelPersonalInfo);
            }
            EasyExcel.write(response.getOutputStream(), ExcelPersonalInfo.class)
                    .autoCloseStream(Boolean.FALSE)// 这里需要设置不关闭流
                    .sheet("个人信息 ")
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(18))// 简单的列宽策略，列宽50
                    .doWrite(excelPersonalInfoList);
        } catch (IOException e) {
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            e.printStackTrace();
            throw new BaseException(ResponseEnum.EXPORT_DATA_ERROR);
        }

    }


    public QueryWrapper<BcraPersonalInfo> selectSearch(BcraPersonalInfoVo bcraPersonalInfoVo) {
        //满足条件的筛选
        QueryWrapper<BcraPersonalInfo> queryWrapper = new QueryWrapper();

        //使用数组传参不生效
        String[] phones = bcraPersonalInfoVo.getPhones();
        String[] roles = bcraPersonalInfoVo.getRoles();

        String status = bcraPersonalInfoVo.getStatus();
        LocalDateTime startDate = bcraPersonalInfoVo.getStartDate();
        LocalDateTime endDate = bcraPersonalInfoVo.getEndDate();

        queryWrapper.eq(StringUtils.isNotBlank(status), "status", status);

        if (phones != null && phones.length != 0) {
            List<String> phonesList = Arrays.asList(phones);
            queryWrapper.in("phone", phonesList);
        }
        if (roles != null && roles.length != 0) {
            List<String> rolesList = Arrays.asList(roles);
            queryWrapper.in("role", rolesList);
        }
        if (startDate != null && endDate != null) {
            queryWrapper.between("create_time", startDate, endDate);
        }
        //安装时间降序排列
        queryWrapper.orderByDesc("create_time");
        return queryWrapper;
    }

}
